/*	Copyright 2007 - Xavier Baro (xbaro@cvc.uab.cat)

	This file is part of eapmlib.

    Eapmlib is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or any 
	later version.

    Eapmlib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __EVOLLEARNER_H__
#define __EVOLLEARNER_H__

#include "EvolutiveLib.h"
#include "Population.h"
#include "Evaluator.h"

namespace Evolutive {
	//! Defines the type of optimization
	enum EVOLUTIVELIB_API OPT_CRITERIA {OPT_MINIMIZE,OPT_MAXIMIZE};

	//! Defines the type of selection
	enum EVOLUTIVELIB_API SEL_METHOD {SELMETHOD_SCORE,SELMETHOD_FASTDIVERSITY,SELMETHOD_DIVERSITY};
	
	class EVOLUTIVELIB_API CEvolLearner
	{
		//! Methods
	public:
		//! Default constructor		
		CEvolLearner(void);
		
		//! Default destructor
		virtual ~CEvolLearner(void);

		//! Evaluation method.
		double Solve(void);
		double Solve(CChromosome &Solution);
		double Solve(CChromosome &Solution,int &Iteration);
		double Solve(int &Iteration);

		//! Sets the maximum number of iterations
		void SetMaxIterations(int NumIterations);

		//! Sets the type of optimization
		void SetOptCriteria(OPT_CRITERIA Criteria);			

		//! Sets the population size
		void SetPopulationSize(int Size);

		//! Sets the codification method
		void SetCodingMethod(CODING_METHOD CodingMethod);	

		//! Sets the evaluator object
		void SetEvaluator(CEvaluator *Evaluator);		

		//! Sets the number of elitist individuals
		void SetNumElitist(int NumIndividuals);

		//! Sets the stop criteria by goal value
		void SetStopValue(double Value);

		//! Sets the selection criteria
		void SetSelCriteria(SEL_METHOD Criteria);

		//! Sets initial population file
		void SetInitialPopulation(CPopulation *InitialPop);

		//! Sets the max number of iterations without improvement. Stop Criteria
		void SetMaxStaticIterations(int NumIterations);

	protected:
		//! Check the stop criterias
		virtual bool ApplyStopCriteria(void);

		//! Performs the evaluation process.
		void EvalPopulation(void);		

		//! Use the apriory knowledge to build the initial population
		virtual void UseAprioriPopulation(void) = 0;

		//! Evolve to the next generation
		virtual void NextGeneration(void) = 0;

		//! Initialize the parent population
		void InitPopulation(void);

		//! Initialize the learner
		virtual void InitLearner(void);

		//! Validate the population and regenerate the invalid individuals
		void ValidatePopulation(void);
					
		//! Attributes
	protected:		
		//! Pointer to the evaluation module
		CEvaluator *m_Evaluator;

		//! Population
		CPopulation m_Population;

		//! Best chromosome
		CChromosome m_BestIndividual;

		//! Best score
		double m_BestScore;

		//! Max number of iterations
		int m_MaxNumIterations;

		//! Type of optimization
		OPT_CRITERIA m_OptCriteria;

		//! Population size
		int m_PopulationSize;

		//! Codification type
		CODING_METHOD m_CodingMethod;

		//! Number of iteration
		int m_IterNum;

		//! Number of elistist individuals
		int m_NumElitist;		

		//! Flag to enable/disable the stop value criteria
		bool m_StopValueEnabled;
	
		//! Goal value. If it is archieved the learning process stops.
		double m_StopValue;

		//! Selection criteria
		SEL_METHOD m_SelMethod;

		//! Initial Population
		CPopulation *m_InitialPopulation;

		//! Stores the maximum allowed iterations without improvement
		int m_StableIters;

		//! Stores the number of iterations with no improvement
		int m_StableCount;		
	};	
}

#endif // __EVOLLEARNER_H__
